package com.finance.scheduler.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.finance.activemq.service.ActiveMqSender;
import com.finance.base.constant.BaseConstants;
import com.finance.base.enums.PackageSizeEnum;
import com.finance.base.enums.StateEnum;
import com.finance.report.bean.pojo.LogisticsData;
import com.finance.report.service.ILogisticsDataService;
import com.finance.report.service.ILogisticsErrorLogService;
import com.finance.scheduler.responsexml.PullLogistics;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by CBWL on 2017/6/7.
 */
@Component
public class LogisticsDataHanler {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ILogisticsDataService logisticsDataService;
    @Resource
    private ILogisticsErrorLogService logisticsErrorLogService;
    @Autowired
    private ActiveMqSender activeMqSender;

    private ObjectMapper om = new ObjectMapper();

    private LogisticsData genDirtyLogisticsData(PullLogistics pullLogistics) {
        LogisticsData dirtyLogisticsData = new LogisticsData();
        String packageSize = pullLogistics.getPackageSize();
        if (StringUtils.isNotBlank(packageSize)) {
            if (BaseConstants.PAKAGESIZE_TYPE_BIG.equals(packageSize)) {
                pullLogistics.setPackageSize(PackageSizeEnum.BIG.getValue() + "");
            } else if (BaseConstants.PAKAGESIZE_TYPE_MIDDLE.equals(packageSize)) {
                pullLogistics.setPackageSize(PackageSizeEnum.MIDDLE.getValue() + "");
            } else if (BaseConstants.PAKAGESIZE_TYPE_SMALL.equals(packageSize)) {
                pullLogistics.setPackageSize(PackageSizeEnum.SMALL.getValue() + "");
            }
        }
        BeanUtils.copyProperties(pullLogistics, dirtyLogisticsData);
        //清洗accept time
        if (null == dirtyLogisticsData.getAcceptTime()) {
            Date acceptTime = dirtyLogisticsData.getWarehouseOutTime();
            acceptTime = acceptTime == null ? dirtyLogisticsData.getSiteInTime() : acceptTime;
            acceptTime = acceptTime == null ? dirtyLogisticsData.getSiteOutTime() : acceptTime;
            acceptTime = acceptTime == null ? dirtyLogisticsData.getSignTime() : acceptTime;
            dirtyLogisticsData.setAcceptTime(acceptTime);
        }
        dirtyLogisticsData.setNameConsignee(this.substring(dirtyLogisticsData.getNameConsignee(),20));
        dirtyLogisticsData.setBusinessRemark(this.substring(dirtyLogisticsData.getBusinessRemark(),200));
        dirtyLogisticsData.setRemark(this.substring(dirtyLogisticsData.getRemark(),200));
        dirtyLogisticsData.setAddressConsignee(this.substring(dirtyLogisticsData.getAddressConsignee(),100));
        dirtyLogisticsData.setSupplierWarehouse(this.substring(dirtyLogisticsData.getSupplierWarehouse(),20));
        return dirtyLogisticsData;
    }

    private String substring(String source,int len){
        if(StringUtils.isBlank(source)) {
            return "";
        }
        if(source.length()>len) {
            return source.substring(0, len);
        }
        return source;
    }

    /**
     * 运单数据清洗
     *
     * @param logisticsData
     * @return
     */
    private LogisticsData purifyLogisticData(LogisticsData logisticsData) {
        LogisticsData pureLogisticsData = new LogisticsData();
        BeanUtils.copyProperties(logisticsData, pureLogisticsData);
        pureLogisticsData.setDirection(-1);
        pureLogisticsData.setOrgcodeAccept("");
        pureLogisticsData.setOrgcodeDelivery("");
        pureLogisticsData.setImportSource(-1);
        pureLogisticsData.setPostmanNo("");
        pureLogisticsData.setExpressScheduleType(-1);
        pureLogisticsData.setSupplierCode("");
        pureLogisticsData.setStatus(-1);
        pureLogisticsData.setTemperature(-1);
        pureLogisticsData.setProvinceConsignee("");
        pureLogisticsData.setCityConsignee("");
        pureLogisticsData.setCountyConsignee("");
        pureLogisticsData.setState(StateEnum.Valid.getState());
        pureLogisticsData.setNodeCurrent("");
        pureLogisticsData.setSigner(logisticsData.getSigner() == 1 ? 1 : 0);//签收方式映射缺失，暂对应解析结果调整；
        return pureLogisticsData;
    }

    @Transactional
    public String proceedData(List<PullLogistics> pullLogisticsList) {
        /**
         * 插库操作
         */
        List<String> mainNoList = new ArrayList<String>();
        String mailNos ="";
        if (pullLogisticsList != null && pullLogisticsList.size() > 0) {
            logger.info("拉取到的运单数量：{}", pullLogisticsList.size());
            LogisticsData pureLogisticsData;
            LogisticsData oldLogisticsData;
            for (PullLogistics pullLogistics : pullLogisticsList) {
                LogisticsData dirtyLogisticsData = this.genDirtyLogisticsData(pullLogistics);
                pureLogisticsData = this.purifyLogisticData(dirtyLogisticsData);
                String tableName = logisticsDataService.getDataTableName(dirtyLogisticsData.getSignTime());
                oldLogisticsData = this.logisticsDataService.getByWaybillNum(tableName, dirtyLogisticsData.getWaybillNum());
                if (oldLogisticsData != null) {
                    this.logger.info("已存在的运单信息，过滤处理，运单号[waybillNum]:{}", oldLogisticsData.getWaybillNum());
                    mainNoList.add(pullLogistics.getWaybillNum());
                    continue;
                }
                String pureLogisticsDataError = null;
                try {
                    BigDecimal weight = pureLogisticsData.getWeight() == null ? new BigDecimal(0) : pureLogisticsData.getWeight().divide(BaseConstants.THOUSAND, BaseConstants.ROUND, RoundingMode.HALF_UP);
                    pureLogisticsData.setWeight(weight);
                    logisticsDataService.add(pureLogisticsData);
                    this.sendMessageToMq(dirtyLogisticsData);//发送消息
                } catch (Exception e) {
                    pureLogisticsDataError = e.getMessage();
                    logger.error(e.getMessage(), e);
                    this.logger.error("【运单数据拉取】存库异常:{}", e.getMessage());
                    if (null == this.logisticsDataService.getByWaybillNum(tableName, dirtyLogisticsData.getWaybillNum())) {
                        //记录插库失败的运单
                        String errorReason = "插入纯数据失败:{" + pureLogisticsDataError + "}";
                        this.logisticsErrorLogService.addErrorLog(dirtyLogisticsData, errorReason, BaseConstants.COMPUTE_TYPE_SAVEPULLDATA);
                    } else {
                        this.logger.info("已存在的运单信息，过滤处理，运单号[waybillNum]:{}", dirtyLogisticsData.getWaybillNum());

                    }
                    continue;
                }
                mainNoList.add(pullLogistics.getWaybillNum());
            }
            mailNos = StringUtils.join(mainNoList, ",");
            this.logger.info("已拉取运单[mailNos]:{}", mailNos);
            this.logger.info("***********************运单拉取结束*****************************");
        }
        return mailNos.toString();
    }

    /**
     * 发送消息
     *
     * @param logisticsData
     */
    public void sendMessageToMq(LogisticsData logisticsData) throws Exception {
        try {
            String val = om.writeValueAsString(logisticsData);
            this.activeMqSender.getAcceptOrderProducerTemplate().sendBody(val);
         } catch (Exception e) {
            this.logger.error(e.getMessage(),e);
            throw e;
        }
    }

}
